package com.jt.fillter;

import com.jt.SecurityMain.LoginUser;
import com.jt.service.UserService;
import com.jt.utils.JwtUtils;
import com.jt.utils.RedisUtils;
import com.mysql.cj.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.Map;
import java.util.Objects;

/*全局过滤器OncePerRequestFilter*/
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private UserService userService;
    @Autowired
    private RedisUtils redisUtils;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        //判断请求方式，排除OPTIONS请求
        if(request.getMethod().toUpperCase().equals("OPTIONS")){
            return ;//通过所有OPTION请求
        }
        String token = request.getHeader("Authorization");
        if (StringUtils.isNullOrEmpty(token)){
            filterChain.doFilter(request,response);
           //如果没有token放行，应为security很多锅炉器，先是usernamePasswordAothencationFilter接下来异常过滤器，接下来还有个FileSEcurityInterceptor过滤器，吐过不返回，就会依次进3个过滤器
            return;
        }
        //2解析token
        Map<String, Object> map = JwtUtils.JieXi(token);
        Map<Object, Object> ResultMap = redisUtils.hmget("loginUser:" + map.get("id").toString());
        LoginUser loginUser = ( LoginUser)ResultMap.get("loginUser");
        if (Objects.isNull(loginUser)){
            throw new RemoteException("该用户未登陆");
        }
        //3将token存入securityContextHolder中、usernamePasswordAuthenticationToken必须传3个参数的构造函数，有个认证set,认证成功就放行
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken=new UsernamePasswordAuthenticationToken(loginUser,null,loginUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
         /*4执行到最后放行*/
        filterChain.doFilter(request,response);
    }


}
